home *** CD-ROM | disk | FTP | other *** search
/ Mac OS 9 Serial Number Archive / SN Archive 2023.11.04.toast / BSNG / SDK / BSNG SDK 2.5 / Example Plugin / Example.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-11  |  14.7 KB  |  632 lines  |  [TEXT/CWIE]

  1. /*
  2.  * $Workfile:: Example.c                                                      $
  3.  * $Revision:: 5                                                              $
  4.  *
  5.  * $Author:: Buck Rogers                                                      $
  6.  * $Modtime:: 11.03.1998 04:34 Uhr                                            $
  7.  *
  8.  * $History:: Example.c                                                       $
  9.  * 
  10.  * *****************  Version 5  *****************
  11.  * User: Buck Rogers  Date: 11.03.1998   Time: 04:34 Uhr
  12.  * Updated in $/BSNG/Plugins/BSNG SDK/Example Plugin
  13.  * example plugin now demonstrates the use of the new controls
  14.  * 
  15.  * *****************  Version 4  *****************
  16.  * User: Buck Rogers  Date: 29.10.1997   Time: 17:42 Uhr
  17.  * Updated in $/BSNG/Plugins/BSNG SDK/Example Plugin
  18.  * example plugin now makes use of the new 'errorText' variable
  19.  * 
  20.  * *****************  Version 3  *****************
  21.  * User: Buck Rogers  Date: 08.10.1997   Time: 02:03 Uhr
  22.  * Updated in $/BSNG/Plugins/BSNG SDK/Example Plugin
  23.  * changed lf to cr in list generation so Mac compatible output is created
  24.  * 
  25.  * *****************  Version 2  *****************
  26.  * User: Buck Rogers  Date: 05.10.1997   Time: 19:24 Uhr
  27.  * Updated in $/BSNG/Plugins/BSNG SDK/Example Plugin
  28.  * Added comments related to the new name, company and numCopies items in the
  29.  * parameter block
  30.  * 
  31.  * *****************  Version 1  *****************
  32.  * User: Buck Rogers  Date: 30.09.1997   Time: 18:31 Uhr
  33.  * Created in $/BSNG/Plugins/BSNG SDK/Example Plugin
  34.  * Adding subproject 'BSNG' to '$/'
  35.  *
  36.  * $NoKeywords::                                                              $
  37.  */
  38.  
  39.  
  40. #include <MixedMode.h>
  41. #include <A4Stuff.h>
  42.  
  43. #include "standard utils.h"
  44. #include "UltraU.h"
  45. #include "BSNG API.h"
  46.  
  47.  
  48. /*    don't touch this __procinfo definition or the calls from native code will crash the machine */
  49.  
  50. ProcInfoType __procinfo = kThinkCStackBased | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(BSNGParamBlockPtr)));
  51.  
  52.  
  53. /*    function prototypes for ANSI C */
  54.  
  55. static void DoInit(BSNGParamBlockPtr inData);
  56. static Boolean DoValidate(BSNGParamBlockPtr inData);
  57. static void DoCalc(BSNGParamBlockPtr inData);
  58. static void DoRandomCalc(BSNGParamBlockPtr inData);
  59. static void DoItemHit(BSNGParamBlockPtr inData);
  60. static Boolean DoAddRandomsToList(BSNGParamBlockPtr inData);
  61. static void DoCleanup(BSNGParamBlockPtr inData);
  62. void main(BSNGParamBlockPtr inData);
  63.  
  64.  
  65. /*    here is where the fun starts :-) */
  66.  
  67. static void DoInit(BSNGParamBlockPtr inData)
  68. {
  69.     StringPtr        aStr = nil;
  70.     
  71.     
  72.     /*    Initialize the Ultra Random Number generator (optional, use MacOS random functions otherwise) */
  73.     
  74.     Ultra_seed1 = inData->randSeed1;
  75.     Ultra_seed2 = inData->randSeed2;
  76.     Ultra_Init();
  77.     
  78.     /*    Give the BSNG App the informations if your plugin can do random calculations and if it can write
  79.         to the serial number list */
  80.     
  81.     inData->wantsRandomButton = true;
  82.     inData->canAddToSNList = true;
  83.     
  84.     /*    Initialize the EditFields with initial default values (optional, they are empty otherwise) */
  85.     /*    if you create a name-based generator please make sure that you copy the name, company and/or numCopies */
  86.     /*    values into the corrosponding fields */
  87.     
  88.     aStr = inData->itemValue[kItemValue1];
  89.     BlockMoveData("\p1234", aStr, 5);
  90.     
  91.     aStr = inData->itemValue[kItemValue2];
  92.     BlockMoveData("\p2345", aStr, 5);
  93.     
  94.     aStr = inData->itemValue[kItemValue3];
  95.     BlockMoveData("\p3456", aStr, 5);
  96.     
  97.     aStr = inData->itemValue[kItemValue4];
  98.     aStr[0] = 0;
  99.     
  100.     /*    Set the default popup menu item to "+" */
  101.     
  102.     inData->selectedPopupItem[kPopupMenu1] = 1;
  103.     
  104.     /*    Uncheck the "Negate  Result" checkbox */
  105.     
  106.     inData->checkboxSelected[kCheckbox1] = false;
  107.     
  108.     /*    Set the default radio button (+) and disable the others in that radio button group */
  109.     
  110.     inData->radioSelected[kRadioButton1] = true;        //    "+"
  111.     inData->radioSelected[kRadioButton2] = false;        //    "-"
  112.     inData->radioSelected[kRadioButton3] = false;        //    "*"
  113.     inData->radioSelected[kRadioButton4] = false;        //  "/"
  114.     
  115.     /*    Tell the BSNG App if the initialisation was successful (it was in our case) */
  116.     
  117.     inData->errorText[0] = 0;
  118.     inData->error = errExtNoErr;
  119.     inData->errorInItem = 0;
  120. }  /* DoInit */
  121.  
  122.  
  123. static Boolean DoValidate(BSNGParamBlockPtr inData)
  124. {
  125.     StringPtr        num1Str = inData->itemValue[kItemValue1];
  126.     StringPtr        num2Str = inData->itemValue[kItemValue2];
  127.     StringPtr        num3Str = inData->itemValue[kItemValue3];
  128.     
  129.     Str31            inputStr    = "\pThe input for ";
  130.     Str31            tooLongStr    = "\p is too long! ";
  131.     Str31            emptyStr    = "\p is empty! ";
  132.     Str63            pleaseStr    = "\p\rPlease enter a number between 1 and 9999.";
  133.     
  134.     Boolean            error = false;
  135.     
  136.     
  137.     /*    we do some simple checks here if the edit fields are not empty or not longer than 8 characters, additionally we could
  138.         also check if the values are really only numbers, but I skipped that because the input filter for the edit fileds
  139.         was set to integer anyway (defined in Constructor) */
  140.     
  141.     inData->errorText[0] = 0;
  142.     
  143.     if ((num1Str[0] < 1) || (num1Str[0] > 4))
  144.     {
  145.         /*    If something was wrong in the input tell the BSNG App what edit field contained wrong values */
  146.         
  147.         inData->errorInItem = kEditItem1;
  148.         error = true;
  149.         
  150.         /*    Build the errorText string (optional), leave errorText empty if you don't want to use this feature */
  151.         
  152.         myAppendPStr(inData->errorText, inputStr);
  153.         myAppendPStr(inData->errorText, "\pNumber 1");
  154.         
  155.         if (num1Str[0] < 1)
  156.         {
  157.             myAppendPStr(inData->errorText, emptyStr);
  158.         }
  159.         else
  160.         {
  161.             myAppendPStr(inData->errorText, tooLongStr);
  162.         }
  163.         
  164.         myAppendPStr(inData->errorText, pleaseStr);
  165.     }
  166.     else if ((num2Str[0] < 1) || (num2Str[0] > 4))
  167.     {
  168.         inData->errorInItem = kEditItem2;
  169.         error = true;
  170.         
  171.         myAppendPStr(inData->errorText, inputStr);
  172.         myAppendPStr(inData->errorText, "\pNumber 2");
  173.         
  174.         if (num2Str[0] < 1)
  175.         {
  176.             myAppendPStr(inData->errorText, emptyStr);
  177.         }
  178.         else
  179.         {
  180.             myAppendPStr(inData->errorText, tooLongStr);
  181.         }
  182.         
  183.         myAppendPStr(inData->errorText, pleaseStr);
  184.     }
  185.     else if ((num3Str[0] < 1) || (num3Str[0] > 4))
  186.     {
  187.         inData->errorInItem = kEditItem3;
  188.         error = true;
  189.         
  190.         myAppendPStr(inData->errorText, inputStr);
  191.         myAppendPStr(inData->errorText, "\pNumber 3");
  192.         
  193.         if (num3Str[0] < 1)
  194.         {
  195.             myAppendPStr(inData->errorText, emptyStr);
  196.         }
  197.         else
  198.         {
  199.             myAppendPStr(inData->errorText, tooLongStr);
  200.         }
  201.         
  202.         myAppendPStr(inData->errorText, pleaseStr);
  203.     }
  204.     
  205.     if (error)
  206.     {
  207.         inData->error = errExtIncorrectValue;
  208.         return (false);
  209.     }
  210.     
  211.     inData->error = errExtNoErr;
  212.     
  213.     return (true);
  214. }  /* DoValidate */
  215.  
  216.  
  217. static void DoCalc(BSNGParamBlockPtr inData)
  218. {
  219.     StringPtr        num1Str = inData->itemValue[kItemValue1];
  220.     StringPtr        num2Str = inData->itemValue[kItemValue2];
  221.     StringPtr        num3Str = inData->itemValue[kItemValue3];
  222.     StringPtr        addResultStr = inData->itemValue[kItemValue4];
  223.     
  224.     long            result = 0L, value = 0L;
  225.     
  226.     
  227.     /*    Convert the first 2 numbers into longs */
  228.     
  229.     StringToNum(num1Str, &result);
  230.     StringToNum(num2Str, &value);
  231.     
  232.     /*    Check the selected popup menu item and calculate with the corresponding operator */
  233.     
  234.     switch (inData->selectedPopupItem[kPopupMenu1])
  235.     {
  236.         case (1):
  237.             result += value;
  238.             break;
  239.         
  240.         case (2):
  241.             result -= value;
  242.             break;
  243.         
  244.         case (3):
  245.             result *= value;
  246.             break;
  247.         
  248.         case (4):
  249.             result /= value;
  250.             break;
  251.         
  252.         default:
  253.             break;
  254.     }
  255.     
  256.     /*    Convert the 3rd number into a long */
  257.     
  258.     StringToNum(num3Str, &value);
  259.     
  260.     /*    Check the radio buttons to get the selected one and calculate with the corresponding operator */    
  261.     
  262.     if (inData->radioSelected[kRadioButton1])
  263.     {
  264.         result += value;
  265.     }
  266.     else if (inData->radioSelected[kRadioButton2])
  267.     {
  268.         result -= value;
  269.     }
  270.     else if (inData->radioSelected[kRadioButton3])
  271.     {
  272.         result *= value;
  273.     }
  274.     else if (inData->radioSelected[kRadioButton4])
  275.     {
  276.         result /= value;
  277.     }
  278.     
  279.     /*    Check if the "Negate Result" checkbox is selected/checked and if so negate the result */
  280.     
  281.     if (inData->checkboxSelected[kCheckbox1])
  282.     {
  283.         result = -result;
  284.     }
  285.     
  286.     /*    Convert the result into a Pascal string */
  287.     
  288.     NumToString(result, addResultStr);
  289.     
  290.     /*    Put the result on the Clipboard so users can copy and paste the serial number into the app they want to register */
  291.     
  292.     addResultStr[addResultStr[0] + 1] = '\0';
  293.     
  294.     ZeroScrap();
  295.     PutScrap(addResultStr[0], 'TEXT', &(addResultStr[1]));
  296. }  /* DoCalc */
  297.  
  298.  
  299. static void DoRandomCalc(BSNGParamBlockPtr inData)
  300. {
  301.     StringPtr        num1Str = inData->itemValue[kItemValue1];
  302.     StringPtr        num2Str = inData->itemValue[kItemValue2];
  303.     StringPtr        num3Str = inData->itemValue[kItemValue3];
  304.     
  305.     unsigned short    i = 0;
  306.     
  307.     
  308.     /*    Create your own random numbers as the random functions are not dependent on user input */
  309.     
  310.     num1Str[0] = 0;                                    /*    empty the string */
  311.     myBaseBRandomPStr(num1Str, 10, 4);                /*    generate 8 random digits */
  312.     
  313.     num2Str[0] = 0;
  314.     myBaseBRandomPStr(num2Str, 10, 4);
  315.     
  316.     num3Str[0] = 0;
  317.     myBaseBRandomPStr(num3Str, 10, 4);
  318.     
  319.     /*    Now we "randomize" the operators */
  320.     
  321.     inData->selectedPopupItem[kPopupMenu1] = (Ultra_short8u() % 4) + 1;            //    % 4 because we have 4 menu item entries in our
  322.                                                                                 //    popup, + 1 because the first menu item entry
  323.                                                                                 //    is equal to 1, not 0
  324.     
  325.     for (i = kRadioButton1; i <= kRadioButton4; i++)                            //    deselect all 4 radio buttons in our radio group
  326.     {
  327.         inData->radioSelected[i] = false;
  328.     }
  329.  
  330.     inData->radioSelected[Ultra_short8u() % 4] = true;                            //    then select/activate a random one
  331.     inData->checkboxSelected[kCheckbox1] = (Ultra_short1() ? true : false);        //    select/check our checkbox randomly
  332.     
  333.     /*    Now we are prepared and can call our Calc algorithm */
  334.     
  335.     DoCalc(inData);
  336. }  /* DoRandomCalc */
  337.  
  338.  
  339. static void DoItemHit(BSNGParamBlockPtr inData)
  340. {
  341.     switch (inData->itemMessage)
  342.     {
  343.         case (200001):
  344.             
  345.             /* The popup menu was opened and closed */
  346.             
  347.             DoCalc(inData);
  348.             break;
  349.         
  350.         case (300000):
  351.         
  352.             /*    The "About this plugin" button was pressed, do whatever you want, I just display a small Alert here */
  353.             
  354.             NoteAlert(1000, nil);
  355.             break;
  356.         
  357.         case (400001):
  358.             
  359.             /* The checkbox was checked/unchecked */
  360.             
  361.             DoCalc(inData);
  362.             break;
  363.         
  364.         case (500001):
  365.         case (500002):
  366.         case (500003):
  367.         case (500004):
  368.             
  369.             /* One of the radio buttons was pressed */
  370.             
  371.             DoCalc(inData);
  372.             break;
  373.         
  374.         default:
  375.             break;
  376.     }
  377. }  /* DoItemHit */
  378.  
  379.  
  380. static Boolean DoAddRandomsToList(BSNGParamBlockPtr inData)
  381. {
  382.     StringPtr        num1Str = inData->itemValue[kItemValue1];
  383.     StringPtr        num2Str = inData->itemValue[kItemValue2];
  384.     StringPtr        num3Str = inData->itemValue[kItemValue3];
  385.     StringPtr        addResultStr = inData->itemValue[kItemValue4];
  386.     
  387.     long            count = 0L;
  388.     short            i = 0;
  389.     OSErr            err = noErr;
  390.     
  391.     
  392.     /*    Write your header to the number list */
  393.     
  394.     count = 28L;
  395.     err = FSWrite(inData->outputRefNum, &count, "BSNG SDK Example Plugin 2.5\r");
  396.     
  397.     /*    Return false if an error occured, the creation of list will then be completly aborted */
  398.     
  399.     if (err != noErr)
  400.     {
  401.         return (false);
  402.     }
  403.     
  404.     count = 28L;
  405.     err = FSWrite(inData->outputRefNum, &count, "===========================\r");
  406.     
  407.     if (err != noErr)
  408.     {
  409.         return (false);
  410.     }
  411.     
  412.     /*    Create numOfListNumbers random serial numbers and write them to the list */
  413.     /*    if you create a name-based generator please make sure that you create at least one number */
  414.     /*    using the name, company and/or numCopies informations. You could create more name-based numbers */
  415.     /*    by using your own name/company database */
  416.     
  417.     for (i = 0; i < inData->numOfListNumbers; i++)
  418.     {
  419.         DoRandomCalc(inData);
  420.         
  421.         if (inData->checkboxSelected[kCheckbox1])
  422.         {
  423.             count = 3L;
  424.             err = FSWrite(inData->outputRefNum, &count, "-((");
  425.         }
  426.         else
  427.         {
  428.             count = 3L;
  429.             err = FSWrite(inData->outputRefNum, &count, "  (");
  430.         }
  431.         
  432.         if (err != noErr)
  433.         {
  434.             return (false);
  435.         }
  436.         
  437.         count = (long) num1Str[0];
  438.         err = FSWrite(inData->outputRefNum, &count, &(num1Str[1]));
  439.         
  440.         if (err != noErr)
  441.         {
  442.             return (false);
  443.         }
  444.         
  445.         count = 3L;
  446.         
  447.         switch (inData->selectedPopupItem[kPopupMenu1])
  448.         {
  449.             case (1):
  450.                 err = FSWrite(inData->outputRefNum, &count, " + ");
  451.                 break;
  452.             
  453.             case (2):
  454.                 err = FSWrite(inData->outputRefNum, &count, " - ");
  455.                 break;
  456.             
  457.             case (3):
  458.                 err = FSWrite(inData->outputRefNum, &count, " * ");
  459.                 break;
  460.             
  461.             case (4):
  462.                 err = FSWrite(inData->outputRefNum, &count, " / ");
  463.                 break;
  464.         }
  465.         
  466.         if (err != noErr)
  467.         {
  468.             return (false);
  469.         }
  470.         
  471.         count = (long) num2Str[0];
  472.         err = FSWrite(inData->outputRefNum, &count, &(num2Str[1]));
  473.         
  474.         if (err != noErr)
  475.         {
  476.             return (false);
  477.         }
  478.     
  479.         count = 1L;
  480.         err = FSWrite(inData->outputRefNum, &count, ")");
  481.         
  482.         if (err != noErr)
  483.         {
  484.             return (false);
  485.         }
  486.     
  487.         count = 3L;
  488.         
  489.         if (inData->radioSelected[kRadioButton1])
  490.         {
  491.             err = FSWrite(inData->outputRefNum, &count, " + ");
  492.         }
  493.         else if (inData->radioSelected[kRadioButton2])
  494.         {
  495.             err = FSWrite(inData->outputRefNum, &count, " - ");
  496.         }
  497.         else if (inData->radioSelected[kRadioButton3])
  498.         {
  499.             err = FSWrite(inData->outputRefNum, &count, " * ");
  500.         }
  501.         else if (inData->radioSelected[kRadioButton4])
  502.         {
  503.             err = FSWrite(inData->outputRefNum, &count, " / ");
  504.         }
  505.         
  506.         if (err != noErr)
  507.         {
  508.             return (false);
  509.         }
  510.         
  511.         count = (long) num3Str[0];
  512.         err = FSWrite(inData->outputRefNum, &count, &(num3Str[1]));
  513.         
  514.         if (err != noErr)
  515.         {
  516.             return (false);
  517.         }
  518.     
  519.         if (inData->checkboxSelected[kCheckbox1])
  520.         {
  521.             count = 1L;
  522.             err = FSWrite(inData->outputRefNum, &count, ")");
  523.         }
  524.         
  525.         count = 3L;
  526.         err = FSWrite(inData->outputRefNum, &count, " = ");
  527.         
  528.         if (err != noErr)
  529.         {
  530.             return (false);
  531.         }
  532.         
  533.         count = (long) addResultStr[0];
  534.         err = FSWrite(inData->outputRefNum, &count, &(addResultStr[1]));
  535.         
  536.         if (err != noErr)
  537.         {
  538.             return (false);
  539.         }
  540.     
  541.         count = 1L;
  542.         err = FSWrite(inData->outputRefNum, &count, "\r");
  543.         
  544.         if (err != noErr)
  545.         {
  546.             return (false);
  547.         }
  548.     }
  549.     
  550.     /* Don't forget this last return */
  551.     
  552.     count = 1L;
  553.     err = FSWrite(inData->outputRefNum, &count, "\r");
  554.     
  555.     if (err != noErr)
  556.     {
  557.         return (false);
  558.     }
  559.     
  560.     return (true);
  561. }  /* DoAddRandomsToList */
  562.  
  563.  
  564. static void DoCleanup(BSNGParamBlockPtr inData)
  565. {
  566. #pragma unused (inData)
  567.  
  568.     /*    We didn't allocate any memory in DoInit, so we can leave this empty, otherwise it would be a VERY good idea
  569.         to deallocate/dispose etc. everything we allocated during our work. If you don't do that we have a nice memory leak */
  570.     
  571. }  /* DoCleanup */
  572.  
  573.  
  574. void main(BSNGParamBlockPtr inData)
  575. {
  576. #if (!GENERATINGPOWERPC)
  577.     EnterCodeResource();
  578. #endif
  579.     
  580.     /*    The message dispatcher */
  581.     
  582.     switch(inData->theMessage)
  583.     {
  584.         case (msgExtInit):
  585.             DoInit(inData);
  586.             break;
  587.         
  588.         case (msgExtCalcHit):
  589.         
  590.             if (DoValidate(inData))
  591.             {
  592.                 DoCalc(inData);
  593.             }
  594.             
  595.             break;
  596.         
  597.         case (msgExtRandomHit):
  598.             DoRandomCalc(inData);
  599.             break;
  600.         
  601.         case (msgExtCreateRandom):
  602.             
  603.             /*    Report to the BSNG App if your list entry was written ok or if we had an error */
  604.             
  605.             if (DoAddRandomsToList(inData))
  606.             {
  607.                 inData->error = errExtNoErr;
  608.             }
  609.             else
  610.             {
  611.                 inData->error = errExtWritingToList;
  612.             }
  613.             
  614.             break;
  615.         
  616.         case (msgExtItemHit):
  617.             DoItemHit(inData);
  618.             break;
  619.         
  620.         case (msgExtCleanup):
  621.             DoCleanup(inData);
  622.             break;
  623.         
  624.         default:
  625.             break;
  626.     }
  627.     
  628. #if (!GENERATINGPOWERPC)
  629.     ExitCodeResource();
  630. #endif
  631. }  /* main */
  632.